﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using WatiN.Core;
using WebAutoUtils;
using WebAutomation;
using WebAutomation.Browsers;
using Form = System.Windows.Forms.Form;
using Label = System.Windows.Forms.Label;

namespace WebAuto
{
    public partial class TestDebug : Form
    {
        private string _codeFile;
        private Thread _thread;
        private WebBrowserObject _browserObject;
        public Dictionary<WebAutomation.WebAuto.TestData, Dictionary<int, List<TestLineResult>>> TestResultsOfTest = new Dictionary<WebAutomation.WebAuto.TestData, Dictionary<int, List<TestLineResult>>>();
        private bool _isRunToCompletion = false;
        private string[] _paramLine = null;
        public delegate void AddDataToTreeview();
        public bool _hasBreakPoint = false;
        private int _currentYPosition = 0;
        public TestDebug()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();


        }

        public void onTestRunCompleteDebug(Dictionary<WebAutomation.WebAuto.TestData, Dictionary<int, List<TestLineResult>>> TestResults, Thread thread)
        {
            TestResultsOfTest = TestResults;
            System.IO.StreamReader file = new System.IO.StreamReader(_codeFile);
            int iCount = 0;
            string line = "";
            while ((line = file.ReadLine()) != null)
            {
                if (!string.IsNullOrEmpty(line))
                {

                    string txtName = "Line_" + iCount;
                    var txt2 = this.Controls.Find(txtName, true);
                    if (txt2 != null)
                    {
                        txt2[0].BackColor = Color.White;
                    }
                    iCount++;
                }
            }

            file.Close();
            bool isFailed=false;
            bool isFrameworkErr = false;
            string failErrorMessage="";
            string frameworkErrorMessage = "";
            _testCompletedStatus(ref isFailed, ref isFrameworkErr, ref failErrorMessage, ref frameworkErrorMessage);
            string message = "Completed.Success";
            if(isFailed)
            {
                message = "Completed.FAILED:\n" + failErrorMessage;
            }
            if (isFrameworkErr)
            {
                message = "Completed.ERROR:\n" + frameworkErrorMessage;
            }
            
            MessageBox.Show(message, "Debug");
            button1.Enabled = true;
            btnStepNext.Enabled = false;
            btnStop.Enabled = false;
        }

        private void _testCompletedStatus(ref bool isFailed, ref bool isFrameworkErr,ref string failErrorMessage,ref string frameworkErrorMessage)
        {

            var itemList = TestResultsOfTest;
            if (itemList.Count() > 0)
            {

                foreach (var items in itemList)
                {
                    var list = items.Value;
                    var secToRun = 0.00;
                    var name = "";
                    var tmpName = "";
                    foreach (var listItem in list.Where(i => i.Key > -1))
                    {
                        foreach (var val in listItem.Value)
                        {
                            isFailed = !val.LinePassed;
                            failErrorMessage = val.LineMessage;
                            if (isFailed)
                            {

                                break;
                            }

                        }

                        if (isFailed)
                        {

                            break;
                        }

                    }

                    if (isFailed)
                    {

                        break;
                    }

                }

                
                string errorMessage = "";
                foreach (var items in itemList)
                {
                    var list = items.Value;
                    var secToRun = 0.00;
                    var name = "";
                    var tmpName = "";
                    foreach (var listItem in list.Where(i => i.Key > -1))
                    {
                        foreach (var val in listItem.Value)
                        {
                            isFrameworkErr = val.IsFrameworkError;
                            frameworkErrorMessage = val.LineMessage;
                            if (isFrameworkErr)
                            {

                                break;
                            }

                        }

                        if (isFrameworkErr)
                        {

                            break;
                        }

                    }

                    if (isFrameworkErr)
                    {

                        break;
                    }

                }


            }



        }




        public void onTestCommandEndDebug(string[] param, int iLineCount, Thread thread, WebBrowserObject browserObject)
        {
            CheckForIllegalCrossThreadCalls = false;
            _thread = thread;
            _browserObject = browserObject;
            _paramLine = param;
            _highlightTestCommand(param[1], iLineCount);
        }


        private void _highlightTestCommand(string commandLine, int iLineCount)
        {
            CheckForIllegalCrossThreadCalls = false;
            string textBoxName = "Line_" + iLineCount;
            var txt = this.Controls.Find(textBoxName, true);
            string labelName = "Line_BP_" + iLineCount;
            var lbl = this.Controls.Find(labelName, true);
            if (txt != null)
            {
                if (txt.Count() > 0)
                {

                    System.IO.StreamReader file = new System.IO.StreamReader(_codeFile);
                    int iCount = 0;
                    string line = "";
                    
                    while ((line = file.ReadLine()) != null)
                    {
                        if (!string.IsNullOrEmpty(line))
                        {
                            string txtName = "Line_" + iCount;
                            var txt2 = this.Controls.Find(txtName, true);
                            if (txt2 != null)
                            {
                                txt2[0].BackColor = Color.White;
                            }
                            iCount++;
                        }
                    }

                   
                    file.Close();
                    
                    //"Line_BP_" + iCount;
                    if(lbl!=null)
                    {
                        if(lbl.Count()>0)
                        {
                            if (lbl[0].Text == "●")
                            {
                                _hasBreakPoint = true;
                            }else
                            {
                                _hasBreakPoint = false;
                            }
                        }
                    }
                    txt[0].BackColor = Color.Yellow;
                    _getTestLineDebugDetails();
                    if (!_isRunToCompletion && _hasBreakPoint)
                    {
                        TestCommands.OnPause();
                        btnStepNext.Enabled = true;
                    }
                  
                }
            }

            btnPause.Enabled = true;

        }

        private void _getTestLineDebugDetails()
        {
            CheckForIllegalCrossThreadCalls = false;
            treeView1.Invoke(new AddDataToTreeview(_addDataToTreeview));
          


        }

        private void _addDataToTreeview()
        {
            string val = "";
            treeView1.Nodes.Clear();
            treeView1.Nodes.Add("BrowserObject", "HTML");
            string htmlVal = TestCommands.Url;
            try
            {
                htmlVal += "~"+_browserObject.Html();
                treeView1.Nodes["BrowserObject"].Nodes.Add(new TreeNode(htmlVal));
            }catch
            {
                treeView1.Nodes["BrowserObject"].Nodes.Add(new TreeNode(htmlVal));
            }

            treeView1.Nodes.Add("BrowserObject1", "IFrames");
            foreach (var items in _browserObject.Frames())
            {
                val += " Name:" + _browserObject.GetIFrameAttributeValue(items.Key,"name");
                val += " ID:" + _browserObject.GetIFrameAttributeValue(items.Key, "id");
                try
                {
                    val += " Src:" + _browserObject.GetIFrameAttributeValue(items.Key, "src");
                }catch
                {
                    val += " Src:";
                }
                val += " HTML:" + _browserObject.HtmlIFrame(items.Key);
                treeView1.Nodes["BrowserObject1"].Nodes.Add(new TreeNode(val));
                val = "";

            }

            if (_paramLine != null)
            {
                string lineCommand = _paramLine[0];
                if (lineCommand=="Exec")
                {
                    treeView1.Nodes.Add("BrowserObjectSQL", "SQL");
                    treeView1.Nodes["BrowserObjectSQL"].Nodes.Add(new TreeNode(_paramLine[1]));

                }
                
            }
            treeView1.Nodes.Add("BrowserObjectTestLine", "CommandResults");
            treeView1.Nodes["BrowserObjectTestLine"].Nodes.Add(new TreeNode("Number : " + TestCommands.TestLineResult.LineNumber.ToString()));
            treeView1.Nodes["BrowserObjectTestLine"].Nodes.Add(new TreeNode("Parameters : " + TestCommands.TestLineResult.LineParameter));
            treeView1.Nodes["BrowserObjectTestLine"].Nodes.Add(new TreeNode("Command : " + TestCommands.TestLineResult.LineCommand));
            treeView1.Nodes["BrowserObjectTestLine"].Nodes.Add(new TreeNode("Sub command : " + TestCommands.TestLineResult.LineSubCommand));
            treeView1.Nodes["BrowserObjectTestLine"].Nodes.Add(new TreeNode("Message : " + TestCommands.TestLineResult.LineMessage));
            treeView1.Nodes["BrowserObjectTestLine"].Nodes.Add(new TreeNode("Passed : " + TestCommands.TestLineResult.LinePassed.ToString()));

            treeView1.Nodes.Add("BrowserObjectDataDB", "Variables-DATA");
            string dataTableCount = TestCommands._dataFromDB.Tables.Count.ToString();
            
            foreach(var items in TestCommands._dataVariables)
            {
                string dtVal = "Data Table Index:" + items.Key;
                foreach (DataRow dr in items.Value.Rows)
                {
                    foreach (DataColumn column in items.Value.Columns)
                    {
                        dtVal += column.ColumnName + ":" + dr[column].ToString();
                    }
                }
                treeView1.Nodes["BrowserObjectDataDB"].Nodes.Add(dtVal);
                dtVal = "";
            }

            
           

            treeView1.Nodes.Add("BrowserObject3", "Elements");
            if (!_hasBreakPoint)
            {
                treeView1.Nodes["BrowserObject3"].Nodes.Add("No break point set.");
            }else{

            try
            {
                if (!chkCaptureElements.Checked)
                {
                    treeView1.Nodes["BrowserObject3"].Nodes.Add("Capture elements has been turned off.");
                }
                else
                {
                    foreach (var items in _browserObject.Elements())
                    {
                        try
                        {
                            string type = items.Value.GetType().ToString();
                            if (!type.Contains("WatiN.Core.ElementContainer`1"))
                            {


                                val += items.Value.ElementHTMLType;
                                val += " Type:" + items.Value.ElementAttributes["Type"];
                                val += " Name:" + items.Value.ElementAttributes["Name"];
                                val += ", ID:" + items.Value.ElementAttributes["ID"];
                                val += ", ClassName:" + items.Value.ElementAttributes["ClassName"];
                                val += ", Style:" + items.Value.ElementAttributes["Style"];
                                val += ", Value:" + items.Value.ElementAttributes["Value"];
                                val += ", Click:" + items.Value.ElementAttributes["Click"];
                                val += ", Change:" + items.Value.ElementAttributes["Change"];
                                val += ", Href:" + items.Value.ElementAttributes["Href"];
                                treeView1.Nodes["BrowserObject3"].Nodes.Add(new TreeNode(val));

                            }

                        }
                        catch
                        {
                        }
                    }
                }
            }catch{}
                }
            if (!_isRunToCompletion)
            {
                btnStepNext.Enabled = true;
            }

        }


        private string _getElementAttributeValue(WatiN.Core.Element element,string attributeName)
        {
            string returnValue = "";
            try
            {
                returnValue = element.GetAttributeValue(attributeName);
            }catch{}

            return returnValue;
        }

        private int _getRowCount(string codeFile)
        {
            int returnValue = 0;
            string line = "";
            System.IO.StreamReader file = new System.IO.StreamReader(codeFile);
            while ((line = file.ReadLine()) != null)
            {
                if (!string.IsNullOrEmpty(line))
                {

                    returnValue++;
                }
            }

            file.Close();


            return returnValue;
        }

        public void PopulateDebugBox(string codeFile)
        {
            _codeFile = codeFile;
            CheckForIllegalCrossThreadCalls = false;
            panel1.Controls.Clear();

            TableLayoutPanel pnlContent = new TableLayoutPanel();
            pnlContent.Dock = DockStyle.Fill;
            pnlContent.AutoScroll = true;
            pnlContent.AutoScrollMargin = new Size(1, 1);
            pnlContent.AutoScrollMinSize = new Size(1, 1);
            pnlContent.RowCount = _getRowCount(codeFile);
            pnlContent.ColumnCount = 2;
            for (int i = 0; i < pnlContent.ColumnCount; i++)
            {
                pnlContent.ColumnStyles.Add(new ColumnStyle());
            }
            pnlContent.ColumnStyles[0].Width = 5;
            pnlContent.ColumnStyles[1].Width = 100;
            this.panel1.Controls.Add(pnlContent); 



           
            string line = "";
            System.IO.StreamReader file = new System.IO.StreamReader(codeFile);
            int iCount = 0;
            while ((line = file.ReadLine()) != null)
            {
                if (!string.IsNullOrEmpty(line))
                {
                    pnlContent.RowStyles.Add(new RowStyle(SizeType.Absolute, 20));

                    Label lblTitle = new Label();
                    lblTitle.Name = "Line_BP_" + iCount;
                    lblTitle.Text = string.Format(">");
                    lblTitle.TabIndex = (iCount * 2);
                    lblTitle.Margin = new Padding(0);
                    lblTitle.Dock = DockStyle.Fill;
                    lblTitle.Width = 20;
                    lblTitle.ForeColor = Color.Black;
                    lblTitle.Click +=new EventHandler(lblTitle_Click);
                    pnlContent.Controls.Add(lblTitle, 0, iCount); 

                    
                    
                    TextBox txtValue = new TextBox();
                    txtValue.Name = "Line_" + iCount;
                    txtValue.TabIndex = (iCount * 2) + 1;
                    txtValue.Margin = new Padding(0);
                    txtValue.Dock = DockStyle.Fill;
                    txtValue.BorderStyle = BorderStyle.FixedSingle;
                    txtValue.Text = line;
                    pnlContent.Controls.Add(txtValue, 2, iCount);
                    //this.richerTextBox1.Text += line + System.Environment.NewLine;
                    iCount++;
                }
            }

    //        this.richerTextBox1.CursorPositionChanged +=
    //new System.EventHandler(this.rtb_CursorPositionChanged);
    //        this.richerTextBox1.SelectionChanged +=
    //            new System.EventHandler(this.rtb_SelectionChanged);

            file.Close();

            
             
        }

        private void TestDebug_MouseClick(object sender, MouseEventArgs e)
        {
            
        }

        private void richerTextBox1_MouseClick(object sender, MouseEventArgs e)
        {
            //_currentYPosition = e.Location.Y + richerTextBox1.Top;
            //this.label3.Top = _currentYPosition;
            //var text = richerTextBox1(_currentYPosition);
        }


        private void rtb_CursorPositionChanged(object sender, System.EventArgs e)
        {
            int line = richerTextBox1.CurrentLine-1;
            int col = richerTextBox1.CurrentColumn;
            int pos = richerTextBox1.CurrentPosition;
            if (line > 0)
            {
                line = line - 1;
            }
            var text = richerTextBox1.Lines[line];
            
            if(!string.IsNullOrEmpty(text))
            {
                int firstcharindex = richerTextBox1.GetFirstCharIndexOfCurrentLine();
                int currentline = richerTextBox1.GetLineFromCharIndex(firstcharindex);
                string currentlinetext = richerTextBox1.Lines[line];
                richerTextBox1.Select(firstcharindex, currentlinetext.Length);

                Font font = new Font("Tahoma", 8, FontStyle.Bold);
                richerTextBox1.SelectionFont = font;
                richerTextBox1.SelectionColor = Color.Red;
                
            }

        }
        private void rtb_SelectionChanged(object sender, System.EventArgs e)
        {
            int start = richerTextBox1.SelectionStart;
            int end = richerTextBox1.SelectionEnd;
            int length = richerTextBox1.SelectionLength;

        }

        private void _runTest()
        {
            button1.Enabled = false;
       

            WebAutomation.WebAuto webAuto = new WebAutomation.WebAuto(_codeFile);
            webAuto.RunTest(onTestRunStart, onTestRunCompleteDebug, null, onTestCommandEndDebug, true, null, General.GetExceptionRules()); 
            

        }

        private void onTestCommandStart(string[] param, int iLineCount, Thread thread, WebBrowserObject browserObject)
        {


        }


        private void onTestRunStart(Dictionary<int, string> TestLines, Thread thread)
        {
            CheckForIllegalCrossThreadCalls = false;



        }

        private void lblTitle_Click(object sender,EventArgs e)
        {
            Label lblTitle = (Label)sender;
            if (lblTitle.Text == ">")
            {
                lblTitle.ForeColor = Color.Red;
                lblTitle.Text = "●";
            }
            else
            {
                lblTitle.ForeColor = Color.Black;
                lblTitle.Text = ">";
            }
        }

        private void btnStepNext_Click(object sender, EventArgs e)
        {
            btnStepNext.Enabled = false;
            btnPause.Enabled = false;
            TestCommands.OnResume();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            btnStepNext.Enabled = true;
            button2.Enabled = true;
            btnPause.Enabled = true;
            btnStop.Enabled = true;
            _runTest();
        }

        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TestDebugData frm = new TestDebugData();
            string nodeParent = "";
            try
            {
                nodeParent = e.Node.Parent.Text;
            }catch{}
            frm.SetDebugData(e.Node.Text, nodeParent);
            frm.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                btnStepNext.Enabled = false;
                _isRunToCompletion = true;
                System.IO.StreamReader file = new System.IO.StreamReader(_codeFile);
                int iCount = 0;
                string line = "";
                while ((line = file.ReadLine()) != null)
                {
                    if (!string.IsNullOrEmpty(line))
                    {
                        string txtName = "Line_" + iCount;
                        var txt2 = this.Controls.Find(txtName, true);
                        if (txt2 != null)
                        {
                            txt2[0].BackColor = Color.White;
                       
                        }
                        iCount++;
                    }
                }

                file.Close();
                TestCommands.RunToCompletion();
            }catch(Exception ex)
            {
                MessageBox.Show("Error when running to completion.\n" + ex.Message, "Error:Run to completion");
            }
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            _isRunToCompletion = false;
            btnStepNext.Enabled = true;
            TestCommands.OnPause();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            TestCommands.OnStop();
            MessageBox.Show("Test has stopped", "Test run");
        }

        private void TestDebug_Load(object sender, EventArgs e)
        {

        }

        private void richTextBox1_Click(object sender, EventArgs e)
        {

        }

        private void richTextBox1_MouseClick(object sender, MouseEventArgs e)
        {
            
        }

       

       

       
        
    }
}
